package com.easymin.weixin.controller.h5.v4;

import com.google.common.base.Preconditions;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.common.WxUtils;
import com.easymin.weixin.common.api.DaijiaApi;
import com.easymin.weixin.common.api.SalesApi;
import com.easymin.weixin.controller.v4.ResultTransport;
import com.easymin.weixin.entity.WxAccount;
import com.easymin.weixin.entity.WxApplication;
import com.easymin.weixin.manager.WxAccountManager;
import com.easymin.weixin.manager.WxApplicationManager;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by shine on 15/12/25.
 */
@RestController
@RequestMapping("h5/v4/dj")
public class DaijiaV4Controller {

  private static final String WX_ACCESS_TOKEN =
      "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";

  private static final String WX_JSAPI_TICKET =
      "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi";

  @Autowired
  private DaijiaApi daijiaApi;
  
  @Autowired
  private SalesApi salesApi;

  @Autowired
  private WxApplicationManager wxApplicationManager;

  @Autowired
  private WxAccountManager wxAccountManager;

  @Autowired
  private RestTemplate restTemplate;

  /**
   * 查询附近的司机人数,默认距离为5公里.
   * 
   * @param appKey 系统key
   * @param lat 纬度
   * @param lng 经度
   * @return JSONObject
   */
  @RequestMapping("coutNearDrivers")
  public JSONObject coutNearDrivers(@RequestParam("appkey") String appKey,
      @RequestParam("lat") Double lat, @RequestParam("lng") Double lng) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    JSONObject jsonObject = daijiaApi.countNearDriver(wxApplication.getAddress(), lng, lat, 5);

    JSONObject result = new JSONObject();
    result.put("count", 0);

    if (jsonObject.getBooleanValue("success")) {
      JSONArray jsonArray = jsonObject.getJSONArray("data");
      int size = jsonArray.size();
      if (size > 0) {
        JSONObject perfect = null;
        for (int i = 0; i < size; i++) {
          JSONObject jo = jsonArray.getJSONObject(i);
          if (i == 0) {
            perfect = jo;
            continue;
          }

          if (perfect.getDoubleValue("driverMeter") > jo.getDoubleValue("driverMeter")) {
            perfect = jo;
          }
        }

        result.put("distance", perfect.getString("driverDistance"));
      }

      result.put("count", size);
    }

    return result;
  }

  /**
   * 预算费用.
   * @param appKey 系统key
   * @param ack 区分公司
   * @param passengerId 客户id
   * @param startLat 开始纬度
   * @param startLng 开始经度
   * @param endLat 结束纬度
   * @param endLng 结束经度
   * @return JSONObject
   */
  @RequestMapping("calculationPrice")
  public JSONObject calculationPrice(@RequestParam("appkey") String appKey, @RequestParam(
      value = "ack", required = false) String ack, @RequestParam(value = "passengerId",
      required = false) Long passengerId, @RequestParam("startLat") Double startLat,
      @RequestParam("startLng") Double startLng,
      @RequestParam(required = false, value = "endLat") Double endLat, @RequestParam(
          required = false, value = "endLng") Double endLng) {


    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    JSONObject jsonObject =
        daijiaApi.calculationPrice(wxApplication.getAddress(), ack, passengerId, startLat,
            startLng, endLat, endLng);

    return jsonObject;
  }

  /**
   * 代驾查询优惠券.
   * @param appKey 系统key
   * @param passengerId 客户id
   * @return JSONArray
   */
  @RequestMapping(value = "findCouponV4", method = RequestMethod.GET)
  public JSONArray findCouponV4(@RequestParam("appkey") String appKey,
      @RequestParam("passengerId") Long passengerId) {


    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    JSONArray jsonArray = salesApi.findCouponV4(passengerId, "daijia", appKey, null);

    return jsonArray;
  }

  /**
   * 查询未完成订单.
   * @param appkey 系统key
   * @param passengerId 客户id
   * @return JSONArray
   */
  @RequestMapping("getRunning")
  public JSONArray getRunning(@RequestParam("appkey") String appkey,
      @RequestParam("passengerId") Long passengerId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appkey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");


    return daijiaApi.findRunning(wxApplication.getAddress(), passengerId);
  }

  /**
   * 预约订单.
   * @param appKey 系统key
   * @param beginAddress 开始地点
   * @param beginAddressDetail 开始详细地址
   * @param beginLat 开始地纬度
   * @param beginLng 开始地经度
   * @param phone 手机号
   * @param ack 区分公司
   * @param endAddress 结束地址
   * @param endAddressDetail 结束详细地址
   * @param endLat 结束地纬度
   * @param endLng 结束地经度
   * @param money 预算金额
   * @param openId 微信id
   * @return JSONObject
   */
  @RequestMapping(value = "makeAnAppointment", method = RequestMethod.POST)
  public JSONObject makeAnAppointment(
		  @RequestParam("appkey") String appKey,
	      @RequestParam("beginAddress") String beginAddress,
	      @RequestParam("beginAddressDetail") String beginAddressDetail,
	      @RequestParam("beginLat") Double beginLat, @RequestParam("beginLng") Double beginLng,
	      @RequestParam("phone") String phone,
	      @RequestParam(value = "ack", required = false) String ack, 
	      @RequestParam(value = "endAddress", required = false) String endAddress, 
	      @RequestParam(value = "endAddressDetail", required = false) String endAddressDetail, 
	      @RequestParam(value = "endLat", required = false) Double endLat, 
	      @RequestParam(value = "endLng",  required = false) Double endLng,
	      @RequestParam(value = "money", required = false) BigDecimal money, 
	      @RequestParam(value = "openId", required = false) String openId) {


    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");
    String response =
        daijiaApi.makeAnAppointmentV4(wxApplication.getAddress(), ack, beginAddress,
            beginAddressDetail, beginLat, beginLng, endAddress, endAddressDetail, endLat, endLng,
            phone, money, openId);

    JSONObject jsonObject = JSON.parseObject(response);

    return jsonObject;
  }

  /**
   * 查询订单信息.
   * @param appKey 系统key
   * @param orderId 订单id
   * @return JSONObject
   */
  @RequestMapping(value = "findOrder")
  public JSONObject findOrder(@RequestParam("appkey") String appKey,
      @RequestParam("orderId") Long orderId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    JSONObject jsonObject = daijiaApi.findOrder(wxApplication.getAddress(), orderId);

    return jsonObject;
  }

  /**
   * 取消订单.
   * @param appKey 系统key
   * @param orderId 订单id
   * @param reson 原因
   * @return Object
   */
  @RequestMapping(value = "cancelOrder", method = RequestMethod.POST)
  public Object cancelOrder(@RequestParam("appkey") String appKey,
      @RequestParam("orderId") Long orderId, @RequestParam("reson") String reson) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");


    return daijiaApi.cancel(wxApplication.getAddress(), orderId, reson);

  }

  /**
   * 获取支付信息.
   * @param appKey 系统key
   * @param orderId 订单id
   * @return Object
   */
  @RequestMapping(value = "prepay", method = RequestMethod.GET)
  public Object prepay(
      @RequestParam("appkey") String appKey, @RequestParam("orderId") Long orderId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    return daijiaApi.clientPayDataDaijia(wxApplication.getAddress(), orderId);

  }

  /**
   * 获取代驾订单是否已经被支付.
   * @param appKey 系统key
   * @param orderId 订单id
   * @return Object
   */
  @RequestMapping(value = "hasPayed", method = RequestMethod.GET)
  public Object hasPayed(@RequestParam("appkey") String appKey,
      @RequestParam("orderId") Long orderId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    return daijiaApi.checkTaskDaijia(wxApplication.getAddress(), orderId);
  }

  /**
   * 进行支付.
   * @param appKey 系统key
   * @param orderId 订单id
   * @param who 支付人member
   * @param payType 支付类型
   * @return ResultTransport
   */
  @RequestMapping(value = "doPay", method = RequestMethod.POST)
  public ResultTransport doPay(@RequestParam("appkey") String appKey,
      @RequestParam("orderId") Long orderId,
      @RequestParam(required = false, value = "who") String who,
      @RequestParam("payType") String payType) {


    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");
    
    return daijiaApi.finishTaskDaijiaV4(wxApplication.getAddress(), orderId, payType, who);

  }

  /**
   * 微信支付.
   * @param appKey 系统key
   * @param orderId 订单id
   * @param openid 微信id
   * @param appid 微信应用Id
   * @param request 判断是否来自微信
   * @return JSONObject
   */
  @RequestMapping(value = "doPayForWx", method = RequestMethod.POST)
  public JSONObject doPayForWx(
      @RequestParam("appkey") String appKey, 
      @RequestParam("orderId") Long orderId,
      @RequestParam("openid") String openid,
      @RequestParam("appid") String appid,
      HttpServletRequest request) {


    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    WxAccount wxAccount = wxAccountManager.findBy(appid, wxApplication.getId());
    Preconditions.checkArgument(null != wxAccount, "appid错误");

    // 判断是否来自微信
    StringBuilder sb = new StringBuilder();
    sb.append(request.getScheme());
    sb.append("://");
    sb.append(request.getServerName());
    int port = request.getServerPort();
    if (port != 80) {
      sb.append(":").append(port);
    }
    sb.append(request.getRequestURI());
    String queryString = request.getQueryString();
    if (StringUtils.isNotBlank(queryString)) {
      sb.append("?");
      sb.append(queryString);
    }

    JSONObject jsonObject = new JSONObject();

    JSONObject jo = daijiaApi.getDjWxPrepayId(wxApplication.getAddress(), orderId, openid);
    jsonObject.put("package", jo.getString("package"));
    jsonObject.put("timestamp", jo.getString("timeStamp"));
    jsonObject.put("url", sb.toString());
    jsonObject.put("nonceStr", jo.getString("nonceStr"));
    jsonObject.put("paySign", jo.getString("paySign"));

    // 获取微信AccessToken
    String response =
        restTemplate.getForObject(WX_ACCESS_TOKEN, String.class, wxAccount.getWxappId(),
            wxAccount.getAppsecret());
    JSONObject ac = JSON.parseObject(response);

    if (ac.containsKey("access_token")) {
      String accessToken = ac.getString("access_token"); // 获取微信access_token

      // 获取jsapi_ticket
      String resp = restTemplate.getForObject(WX_JSAPI_TICKET, String.class, accessToken);
      JSONObject ticketJson = JSON.parseObject(resp);
      if (ticketJson.containsKey("ticket")) {

        String ticket = ticketJson.getString("ticket");

        jsonObject.put("jsapi_ticket", ticket);

        Map<String, Object> signParams = new HashMap<>();
        signParams.put("jsapi_ticket", ticket);
        signParams.put("timestamp", jo.getString("timeStamp"));
        signParams.put("url", sb.toString());
        signParams.put("nonceStr", jo.getString("nonceStr"));

        jsonObject.put("signature", WxUtils.buildSha1Sign(signParams));
      }
    }

    return jsonObject;
  }
}
